<template>
  <div :class="['m-sider', collapsed ? 'm-sider-small' : '']">
    <Sider
      :collapsedWidth="60"
      :width="150"
      :collapsed="collapsed"
      class="platform-side"
    >
      <div class="menu-list">
        <a-menu
          mode="inline"
          class="m-menu"
          :inlineIndent="24"
          @click="menuClick"
          v-model:selectedKeys="selectedKeys"
          @openChange="onOpenChange"
          v-bind="{ ...(collapsed ? {} : { openKeys: targetPathId }) }"
        >
          <template v-for="item in menuData">
            <a-menu-item
              :key="item.key"
              v-if="!item.children || item.children.length === 0"
            >
              <MIcon
                :type="item.icon"
                style="font-size: 16px; margin-right: 5px"
              />
              <span>{{ item.name }}</span>
            </a-menu-item>
            <template v-else>
              <m-sub-menu :key="item.key" :menu-info="item" />
            </template>
          </template>
        </a-menu>
      </div>

      <div class="menu-footer">
        <Icon
          v-if="collapsed"
          type="menu-unfold"
          style="cursor: pointer; color: #333333"
          @click="toggle"
        />
        <Icon
          v-else
          type="menu-fold"
          style="cursor: pointer; color: #333333"
          @click="toggle"
        />
      </div>
    </Sider>
  </div>
</template>

<script>
import { Layout, Menu, Icon } from "ant-design-vue";
import MIcon from "@/components/MIcon";
import getMenuData from "./menuData";
import matchMenu from "./matchMenu";
import { mapState } from "vuex";

const { Sider } = Layout;

const MSubMenu = {
  template: `
      <a-sub-menu :key="menuInfo.key" v-bind="$props" v-on="$listeners">
        <span slot="title">
          <m-icon :type="menuInfo.icon" style="font-size: 16px; margin-right: 3px" />
          <span> {{ menuInfo.name }}</span>
        </span>
        <template v-for="item in menuInfo.children">
          <a-menu-item v-if="!item.children || item.children.length === 0" :key="item.key">
            <span>{{ item.name }}</span>
          </a-menu-item>
          <m-sub-menu v-else :key="item.key" :menu-info="item" />
        </template>
      </a-sub-menu>
    `,
  name: "MSubMenu",
  // must add isSubMenu: true
  isSubMenu: true,
  props: {
    ...Menu.SubMenu.props,
    // Cannot overlap with properties within Menu.SubMenu.props
    menuInfo: {
      type: Object,
      default: () => ({}),
    },
  },
  components: { MIcon },
};

export default {
  name: "m-sider",
  components: { MIcon, Sider, Icon, "m-sub-menu": MSubMenu },
  data() {
    return {
      collapsed: false,
      targetPathId: [],
      selectedKeys: [],
    };
  },
  mounted() {
    const { path } = this.$route;
    const { currentKeys, openKeys } = matchMenu(this.menuData, path);
    this.selectedKeys = currentKeys;
    this.targetPathId = openKeys;
  },
  computed: {
    ...mapState("user", ["permission"]),
    menuData() {
      return getMenuData(this.permission || {}).filter((item) => !!item.isAuth);
    },
  },
  methods: {
    onOpenChange(openKeys) {
      this.targetPathId = openKeys || [];
    },
    menuClick(e) {
      console.log(e);
      this.$router.push({ name: e.key });
    },
    toggle() {
      this.collapsed = !this.collapsed;
    },
  },
  watch: {
    $route: {
      handler(val) {
        const { path } = val;
        const { currentKeys, openKeys } = matchMenu(this.menuData, path);
        this.selectedKeys = currentKeys;
        this.targetPathId = openKeys;
      },
      // 深度观察监听
      deep: true,
    },
  },
};
</script>
<style lang="less" scoped>
.m-sider {
  position: relative;
  height: 100%;
  background: #fff;

  /deep/.ant-menu-inline,
  .ant-menu-vertical,
  .ant-menu-vertical-left {
    border: 0;
  }

  .platform-side {
    width: 100%;
    height: 100%;
    background: #fff;
    .menu-list {
      width: 100%;
      overflow-y: auto;
      overflow-x: hidden;
      height: calc(100% - 40px);
      .m-menu {
        width: 100%;
        height: 100%;
      }
    }
    .menu-footer {
      display: block;
      position: absolute;
      left: 20px;
      bottom: 10px;
      z-index: 999;
    }
  }
}

.m-sider-small {
  /deep/.ant-menu-inline-collapsed {
    width: 60px;
    .ant-menu-item {
      padding: 0 calc(50% - 18px / 2) !important;
    }
    .ant-menu-submenu-title {
      padding: 0 calc(50% - 18px / 2) !important;
    }
    .ant-menu-submenu-title .iconfont {
      font-size: 18px !important;
    }
    .ant-menu-submenu-title .iconfont + span {
      display: inline-block;
      max-width: 0;
      opacity: 0;
    }
    .ant-menu-item .iconfont + span {
      display: inline-block;
      max-width: 0;
      opacity: 0;
    }
  }
}
</style>
